package com.atwisdom.star.core.dsl.functionClass.statistics.Impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.util.JsonUtil;
import com.atwisdom.star.common.vo.ModelType;
import com.atwisdom.star.common.vo.PageInfo;
import com.atwisdom.star.core.dao.pojo.functionClass.statistics.StatisticsInstance;
import com.atwisdom.star.core.dao.pojo.functionClass.statistics.StatisticsInstanceHistory;
import com.atwisdom.star.core.dao.pojo.functionClass.statistics.StatisticsModel;
import com.atwisdom.star.core.dao.service.functionClass.statistics.StatisticsInstanceHistoryService;
import com.atwisdom.star.core.dao.service.functionClass.statistics.StatisticsInstanceService;
import com.atwisdom.star.core.dao.service.functionClass.statistics.StatisticsModelService;
import com.atwisdom.star.core.dsl.cache.ModelCacheDslService;
import com.atwisdom.star.core.dsl.functionClass.statistics.StatisticsInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.consume.Impl.ConsumeInstanceDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.resource.Impl.ResourceInstanceDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.utils.*;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.googlecode.aviator.AviatorEvaluator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StatisticsInstanceDslServiceImpl implements StatisticsInstanceDslService {

    private StatisticsModelService statisticsModelService;
    private StatisticsInstanceService statisticsInstanceService;
    private StatisticsInstanceHistoryService statisticsInstanceHistoryService;


    private ConsumeInstanceDslServiceImpl consumeInstanceDslService;

    private ResourceInstanceDslServiceImpl resourceInstanceDslService;

    private QueryBuilder queryBuilder;

    private ModelCacheDslService modelCacheDslService;

    @Autowired
    public void setModelCacheDslService(ModelCacheDslService modelCacheDslService) {
        this.modelCacheDslService = modelCacheDslService;
    }

    @Autowired
    public void setStatisticsModelService(StatisticsModelService statisticsModelService) {
        this.statisticsModelService = statisticsModelService;
    }

    @Autowired
    public void setStatisticsInstanceService(StatisticsInstanceService statisticsInstanceService) {
        this.statisticsInstanceService = statisticsInstanceService;
    }

    @Autowired
    public void setStatisticsInstanceHistoryService(StatisticsInstanceHistoryService statisticsInstanceHistoryService) {
        this.statisticsInstanceHistoryService = statisticsInstanceHistoryService;
    }

    @Autowired
    public void setConsumeInstanceDslService(ConsumeInstanceDslServiceImpl consumeInstanceDslService) {
        this.consumeInstanceDslService = consumeInstanceDslService;
    }
    @Autowired
    public void setResourceInstanceDslService(ResourceInstanceDslServiceImpl resourceInstanceDslService) {
        this.resourceInstanceDslService = resourceInstanceDslService;
    }


    @Autowired
    public void setQueryBuilder(QueryBuilder queryBuilder) {
        this.queryBuilder = queryBuilder;
    }


    /**
     * 查询全部摘要（通用）
     * @return 返回搞要列表
     */
    @Override
    public List<JSONObject> queryAllInfo() {
        try {
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildInfoSelection(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, null, "className,updateTime");
            List<StatisticsInstance> list = statisticsInstanceService.list();
            List<JSONObject> jsonObjectList = new ArrayList<>();
            list.forEach(ins-> jsonObjectList.add(ins.getInfoJsonObject()));
            return jsonObjectList;
        }catch (Exception ex){
            throw new BusinessException("999999", "无条件查询所有模型信息！");
        }
    }

    /**
     * 分页查询全部摘要（通用）
     * @param pageNumber 参数
     * @param pageSize 参数
     * @param orderBy 参数
     * @return 返回全部搞要列表
     *
     */
    @Override
    public PageInfo queryAllInfoByPage(int pageNumber, int pageSize, String orderBy) {
        try {
            Page<StatisticsInstance> pageInfo = new Page<>(pageNumber, pageSize);
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildInfoSelection(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper,true);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询摘要模型信息！",ex);
        }
    }

    /**
     * 查询全部数据（通用）
     *
     * @return 返回结果
     */
    @Override
    public List<JSONObject> queryAll() {
        try {
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildOrderBy(queryWrapper,null,"className,updateTime");
            List<StatisticsInstance> list = statisticsInstanceService.list();
            return this.getStatisticsInsJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "无条件查询所有模型信息！");
        }
    }

    /**
     * 分页无条件查询模型信息
     *
     * @param pageNumber 参数
     * @param pageSize 参数
     * @param orderBy 参数
     * @return 返回值
     */
    @Override
    public PageInfo listAllByPage(int pageNumber,int pageSize,String orderBy) {
        try {
            Page<StatisticsInstance> pageInfo = new Page<>(pageNumber, pageSize);
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper,false);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询模型信息！");
        }
    }

    /**
     * 查询模型
     *
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    @Override
    public List<JSONObject> query(String condition,String className,String orderBy) {
        try{
            condition = queryBuilder.transformOperator(condition);
            condition = this.transformConditionForStatistics(condition,className);
            orderBy =   this.transformOrderByForStatistics(condition,className,orderBy);
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq("published", true);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            List<StatisticsInstance> list = statisticsInstanceService.list(queryWrapper);
            return this.getStatisticsInsJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "查询模型失败！",ex);
        }
    }
    /**
     * 查询实例容器hier
     * @param id 参数
     * @return 返回hier
     */
    public JSONObject queryHierById( Long id) {
        try {
            StatisticsInstance statisticsInstance = this.statisticsInstanceService.getById(id);
            return statisticsInstance.getHier();
        }catch (Exception ex){
            throw new BusinessException("999999", "查询容器信息失败！");
        }
    }

    /**
     * 按条件分页查询实例摘要
     *
     * @param pageNumber 查询参数
     * @param pageSize 查询参数
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
   public PageInfo queryInfoByPage(int pageNumber,int pageSize, String condition,String className,String orderBy){
       try {
           Page<StatisticsInstance> pageInfo = new Page<>(pageNumber, pageSize);
           condition = queryBuilder.transformOperator(condition);
           condition = this.transformConditionForStatistics(condition,className);
           orderBy =   this.transformOrderByForStatistics(condition,className,orderBy);
           QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
           queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
           queryWrapper.eq("published", true);
           queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
           queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
           return getPageInfoResult(pageInfo, queryWrapper,true);
       }catch (Exception ex){
           throw new BusinessException("999999", "分页无条件查询模型信息！");
       }
    }

    /**
     * 按条件分页查询实例
     *
     * @param pageNumber 查询参数
     * @param pageSize 查询参数
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    public PageInfo queryByPage(int pageNumber,int pageSize, String condition,String className,String orderBy){
        try {
            Page<StatisticsInstance> pageInfo = new Page<>(pageNumber, pageSize);
            condition = queryBuilder.transformOperator(condition);
            condition = this.transformConditionForStatistics(condition,className);
            orderBy =   this.transformOrderByForStatistics(condition,className,orderBy);
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq("published", true);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper,false);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询模型信息！");
        }
    }

    /**
     * 添加模型
     *
     * @param type 参数
     * @param className 参数
     * @param name 参数
     * @return 返回值
     */
    @Override
    public JSONObject add(String type, String className,String name) {
        if (existModel(type, className)) {
            try {
                StatisticsModel statisticsModel = this.modelCacheDslService.queryModel(ModelType.Statistics.getCode(), className);
                String hierType = statisticsModel.getType();
                JSONObject hierJson = statisticsModel.getHierProperties();
                StatisticsInstance instance = new StatisticsInstance(statisticsModel, new JSONObject());
                JSONObject web = statisticsModel.getWeb();
                // 查询指定的数据源，并获取数据
                JSONArray contentJsonArray = updateContentValue(hierJson, web);

                instance.setType(hierType);
                instance.setClassName(className);
                instance.setVersion(statisticsModel.getVersion());
                instance.setName(name);
                instance.setPublished(statisticsModel.getPublished());
                instance.setWeb(web);
                instance.setOthers(statisticsModel.getOthers());
                instance.setHier(hierJson);
                this.statisticsInstanceService.save(instance);
                //添加历史
                StatisticsInstanceHistory statisticsInstanceHistory = new StatisticsInstanceHistory();
                BeanUtils.copyProperties(instance, statisticsInstanceHistory);
                statisticsInstanceHistory.setId(null);
                statisticsInstanceHistoryService.save(statisticsInstanceHistory);

                JSONObject instanceJson = JsonUtil.toJSONObject(instance);
                instanceJson.put("hier", contentJsonArray);
                instanceJson.put("web", instance.getWeb());

                return instanceJson;
            } catch (Exception ex) {
                throw new BusinessException("999999", "初始化实例失败！", ex);
            }
        } else {
            throw new BusinessException("999999", "模型不存在,创建实例失败！");
        }
    }

    /**
     * 将计算所得的结果，更新到content 中
     * @param hierJson
     * @param web
     * @return
     */
    private JSONArray updateContentValue(JSONObject hierJson, JSONObject web) {
        TreeMap<String, Object> instanceData = fetchInstanceData(web.getJSONArray("source"));
        JSONArray contentJsonArray = hierJson.getJSONArray("content");
        // 开始计算结果
        log.info("instanceData = {}", instanceData);
        Map valueMap = handleExpression(contentJsonArray, instanceData);
        for (int i = 0; i < contentJsonArray.size(); i++) {
            JSONObject content = contentJsonArray.getJSONObject(i);
            Object newValue = valueMap.get(content.getString("key"));
            if (Objects.nonNull(newValue)) {
                content.put("value", newValue);
            }
            contentJsonArray.set(i, content);
        }
        hierJson.put("content", contentJsonArray);
        return contentJsonArray;
    }


    /**
     * 计算公式结果
     * @param contentJsonArray 公式配置
     * @param instanceDataMap 计算所需要的数据源
     * 从instanceDataJson中取数据，进行替换
     */
    private Map handleExpression(JSONArray contentJsonArray, TreeMap<String, Object> instanceDataMap) {
        Map expressionMap =  new HashMap<String, Object>();
        for (int i = 0; i < contentJsonArray.size(); i++) {
            JSONObject contentJson = contentJsonArray.getJSONObject(i);
            String expression = contentJson.getString("expression");
            expression = handleSourceData(instanceDataMap, expression);
            // 处理sum 的情况
            String parentId = contentJson.getString("id");
            expression = handleSum(contentJsonArray, parentId, expression);
            expressionMap.put(contentJson.getString("key"), expression);
        }
        // 处理所有引用的节点
        Map paramMap = initParamMap(expressionMap);
        paramMap = calculateValue(expressionMap, paramMap);
        return paramMap;
    }

    /**
     * 将sum 替换为普通加法
     * @param contentJsonArray
     * @param parentId
     * @param expression
     * @return
     */
    private String handleSum(JSONArray contentJsonArray, String parentId, String expression) {
        if (expression.contains("sum()")) {
            List<String> factorList = new ArrayList<>();
            // 查询所有下级，切换为加法公式
            for (int j = 0; j < contentJsonArray.size(); j++) {
                JSONObject childJson = contentJsonArray.getJSONObject(j);
                JSONArray prevArray = childJson.getJSONArray("prev");
                boolean present = prevArray.stream().filter(m -> String.valueOf(m).equals(parentId)).findAny().isPresent();
                if (present) {
                    factorList.add(childJson.getString("key"));
                }
            }
            String newExpression = factorList.stream().collect(Collectors.joining("+", "(", ")"));
            expression = expression.replaceAll("sum\\(\\)", newExpression);
        }
        return expression;
    }

    /**
     * 将expressionMap中的公式，循环计算出结果，并放放到paramMap中当作新的参数
     * @param expressionMap
     * @param paramMap
     */
    private Map calculateValue(Map expressionMap, Map paramMap) {
        while (expressionMap.size() > 0) {
            int originSize = expressionMap.size();
            Iterator<Map.Entry<String, Object>> tempIterator = expressionMap.entrySet().iterator();
            while (tempIterator.hasNext()) {
                Map.Entry<String, Object> entry = tempIterator.next();
                String tempExpression = String.valueOf(entry.getValue());
                Object calcResult = AviatorEvaluator.execute(tempExpression, paramMap);
                Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
                boolean isNumber = pattern.matcher(String.valueOf(calcResult)).matches();
                if (isNumber) {
                    paramMap.put(entry.getKey(), calcResult);
                    tempIterator.remove();
                }
            }
            if (originSize == expressionMap.size()) {
                log.info("expression = {}, paramMap = {}", expressionMap, paramMap);
                throw new BusinessException("根据公式无法计算出结果");
            }
        }
        return paramMap;
    }

    /**
     * 将所有不需要计算的，可以直接用做参数的，放入到参数集合中
     * @param expressionMap
     */
    private Map initParamMap(Map expressionMap) {
        Map paramMap =  new HashMap<String, Object>();
        Iterator<Map.Entry<String, Object>> iterator = expressionMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
            boolean isNumber = pattern.matcher(String.valueOf(entry.getValue())).matches();
            // 公式map中是数字，说明不需要计算
            if (isNumber) {
                paramMap.put(entry.getKey(), Double.valueOf(String.valueOf(entry.getValue())));
                iterator.remove();
            }
        }
        return paramMap;
    }

    /**
     * 处理 soure 数据，即从实例查询出来的数据
     * @param instanceDataMap
     * @param expression
     * @return
     */
    private String handleSourceData(TreeMap<String, Object> instanceDataMap, String expression) {
        String newExpression =  expression;
        newExpression =  newExpression.replaceAll("[\\[\\]\\(\\)\\+\\-*/]", ",");
        String[] split = newExpression.split(",");
        List<String> factorList = Arrays.stream(split).filter(d -> !"".equals(d)).collect(Collectors.toList());
        JSONObject instanceDataJson = new JSONObject(instanceDataMap);
        List<String> factorValueList = new ArrayList(factorList.size());
        factorList.forEach(c->{
            Object value = JsonUtil.get(instanceDataJson, c);
            factorValueList.add(String.valueOf(value));
        });
        for (int i = 0; i < factorList.size(); i++) {
            if (!"null".equals(factorValueList.get(i))) {
                expression = expression.replaceAll(factorList.get(i), factorValueList.get(i));
            }
        }
        log.info("after handling instanceSource, expression = {}", expression);
        return expression;
    }

    /**
     * "source": [
     * {
     * "name": "source1",
     * "model": [
     * "consume",
     * "rawMaterial",
     * "simple1"
     * ]
     * }
     * ],
     * 根据指定的数据源获取数据
     * @param sourceArray
     * @return
     */
    private TreeMap<String, Object> fetchInstanceData(JSONArray sourceArray) {
        TreeMap<String, Object> resultMap = new TreeMap(new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return Integer.valueOf(s1.length()).compareTo(Integer.valueOf(s2.length()));
            }
        });
        if (CollectionUtil.isNotEmpty(sourceArray)) {
            for (int i = 0; i < sourceArray.size(); i++) {
                JSONObject source = sourceArray.getJSONObject(i);
                String name = source.getString("name");
                JSONArray model = source.getJSONArray("model");
                ModelType modelType = ModelType.getByCode(model.getString(0));
                String instanceType = model.getString(1);
                String instanceClassName = model.getString(2);
                String condition = " type = '"+ instanceType +"'";
                List<JSONObject> instanceList = new ArrayList<>();
                switch (modelType) {
                    case Consume:
                        instanceList = consumeInstanceDslService.query(condition, instanceClassName, "");
                        break;
                    case Resource:
                        instanceList = resourceInstanceDslService.query(condition, instanceClassName, "");
                        break;
                    default:
                        break;
                }
                String path = source.getString("path");
                if (StrUtil.isBlank(path)) {
                    path = "0.values";
                }
                JSONArray contentAry = JSONArray.parseArray(JSONArray.toJSONString(instanceList));
                Object dataResult = JsonUtil.get(contentAry, path);
                resultMap.put(name, dataResult);

            }
        }
        return resultMap;
    }



    /**
     * 根据link 创建实例
     * @param link 创建实例参数
     */
    private void createInstance(JSONObject link){
        if (link == null) {
            return;
        }
        String id = link.getString("id");
        if (StringUtils.isNotBlank(id)) {
            return;
        }

        String type = link.getString("type");
        String className = link.getString("className");
        if (StringUtils.isBlank(type) || StringUtils.isBlank(className)) {
            return;
        }
        ModelType modelType = ModelType.getByCode(type);
        JSONObject jsonObject;
        switch (modelType){
            case Consume:
                jsonObject = consumeInstanceDslService.add(type, className, className,null);
                link.put("id",jsonObject.getString("id"));
                break;
            case Resource:
                jsonObject = resourceInstanceDslService.add(type, className, className,null);
                link.put("id",jsonObject.getString("id"));
                break;
            case Statistics:
                jsonObject= this.add(type, className, className);
                link.put("id",jsonObject.getString("id"));
                break;
            default:
                break;
        }
    }

    /**
     * 更新模型属性字段
     * 更新，需要同步更新实例，同步更新历史数据
     * 1、className 和 自定字段
     *
     * @param jsonObject 参数
     * @return 返回值
     */
    @Override
    public JSONObject updateById(JSONObject jsonObject) {
        String id = jsonObject.getString("id");
        if(StringUtils.isBlank(id)){
            throw new BusinessException("999999", "更新id为空操作失败！");
        }
        try {
            StatisticsInstance sourceInstance = statisticsInstanceService.getById(id);
            if(sourceInstance==null){
                throw new BusinessException("999999", "要更新实例不存在，操作失败！");
            }

            StatisticsModel model = this.modelCacheDslService.queryModel(ModelType.Statistics.getCode(), sourceInstance.getClassName());
            StatisticsInstance statisticsInstance =new StatisticsInstance(model,jsonObject,sourceInstance.getValues());
            statisticsInstanceService.getBaseMapper().updateById(statisticsInstance);

            //添加历史
            StatisticsInstanceHistory statisticsInstanceHistory = new StatisticsInstanceHistory();
            BeanUtils.copyProperties(statisticsInstance,statisticsInstanceHistory);
            statisticsInstanceHistory.setId(null);
            this.statisticsInstanceHistoryService.save(statisticsInstanceHistory);
            return statisticsInstance.getInsJsonObject(model);
        }catch (Exception ex){
            throw new BusinessException("999999", "更新模型实例失败！");
        }
    }

    /**
     * 更新实例hier
     * @param jsonObject 更新参数
     * @return 返回更新的实例
     */
    public JSONObject updateHier(JSONObject jsonObject){
        String id = jsonObject.getString("id");
        String className = jsonObject.getString("className");
        JSONObject hier = jsonObject.getJSONObject("hier");

        StatisticsModel model = this.modelCacheDslService.queryModel(ModelType.Statistics.getCode(), className);
        if(model==null){
            throw new BusinessException("999999", "模型不存在,更新实例Hier失败！");
        }

        JSONObject hierProperties = model.getHierProperties();
        if(hierProperties==null || hierProperties.size() <1){
            throw new BusinessException("999999", "模型hierProperties没有配置,更新实例Hier失败！");
        }

        String hierType = hier.getString("type");
        String hierPropType = hierProperties.getString("type");
        if(StringUtils.isBlank(hierType) || StringUtils.isBlank(hierPropType) || !hierType.equalsIgnoreCase(hierPropType)){
            throw new BusinessException("999999", "容器类型type与模型定义type不一致,更新实例Hier失败！");
        }

        try{
            JSONObject hierJson = queryBuilder.fetchHierBy(hierProperties, hier);
            this.dealHierLinkInstance(hierJson);
            StatisticsInstance statisticsInstance = this.statisticsInstanceService.getById(id);
            statisticsInstance.setHier(hierJson);
            this.statisticsInstanceService.updateById(statisticsInstance);

            //添加历史
            StatisticsInstanceHistory statisticsInstanceHistory = new StatisticsInstanceHistory();
            BeanUtils.copyProperties(statisticsInstance,statisticsInstanceHistory);
            statisticsInstanceHistory.setId(null);
            this.statisticsInstanceHistoryService.save(statisticsInstanceHistory);
            return statisticsInstance.getInsJsonObject(model);
        }catch (Exception ex){
            throw new BusinessException("999999", "更新实例Hier失败！",ex);
        }
    }


    /**
     * 处理hierLink
     * @param hier 参数
     */
    private void dealHierLinkInstance(JSONObject hier){
        JSONArray tempContent = hier.getJSONArray("content");
        JSONArray content = new JSONArray();
        for (int i = 0; i < tempContent.size(); i++) {
            JSONObject contentJson = tempContent.getJSONObject(i);
            JSONObject link = contentJson.getJSONObject("link");
            this.createInstance(link);
            contentJson.put("link",link);
            content.add(contentJson);
        }
        hier.put("content",content);
    }


    /**
     * 更新模型属性字段
     * 更新，需要同步更新实例，同步更新历史数据
     * 1、className 和 自定字段
     *
     * @param jsonObjectList 参数
     * @return 返回值
     */
    @Override
    public List<JSONObject> updateByIds(List<JSONObject> jsonObjectList) {
        List<JSONObject> resultJsonList = new ArrayList<>();
        jsonObjectList.forEach(j->{
            JSONObject jsonObject = this.updateById(j);
            resultJsonList.add(jsonObject);

        });
        return resultJsonList;
    }


    /**
     * 按类型和类名更新模型实例（配置阶段）
     * @param jsonObject 类型
     * @return 返回模型记录
     */
    @Override
    public List<JSONObject> updateClassName(JSONObject jsonObject) {
        String type = jsonObject.getString("type");
        String className = jsonObject.getString("className");
        if (StringUtils.isBlank(type) || StringUtils.isBlank(className)) {
            throw new BusinessException("999999", "更新模型实例：type,className都不能为空！");
        }

        if (!this.existModel(type, className)) {
            throw new BusinessException("999999", "模型不存在，更新模型实例失败！");
        }

        try {
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("className", className);
            queryWrapper.eq("type", type);
            queryWrapper.eq("published", true);
            List<StatisticsInstance> instances = this.statisticsInstanceService.list(queryWrapper);
            List<JSONObject> resList = new ArrayList<>();
            instances.forEach(ins->{
                jsonObject.put("id",ins.getId());
                JSONObject upJsonObject = this.updateById(jsonObject);
                resList.add(upJsonObject);
            });
            return resList;
        } catch (Exception ex) {
            throw new BusinessException("999999", "更新模型类型和类名", ex);
        }
    }


    /**
     * 按ids删除模型
     * @param ids id列表
     * @return 返回结果
     */
    public boolean deleteByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            throw new BusinessException("999999", "ids列表不能为空，删除模型失败！");
        }
        //删除缓存
        try {
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", ids);
            queryWrapper.eq("published", true);
            //删除实例
            this.statisticsInstanceService.realDelete(queryWrapper);
            return true;
        } catch (Exception ex) {
            throw new BusinessException("999999", "按ids删除模型失败！", ex);
        }
    }

    /**
     * 接className删除
     * 1、删除实例、2、删除历史 3、更新redis
     *
     * @param className 模型类名
     * @return 返回值
     */
    @Override
    public boolean deleteByClassName(String className)  {
        if (StringUtils.isBlank(className)) {
            throw new BusinessException("999999", "模型类名称不能为空,删除模型实例失败！");
        }
        //删除缓存
        try {
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("className", className);
            queryWrapper.eq("published", true);
            //删除模型
            this.statisticsInstanceService.realDelete(queryWrapper);
            return true;
        } catch (Exception ex) {
            throw new BusinessException("999999", String.format("删除模型%s失败!", className), ex);
        }
    }

    /**
     * 批量删除
     *
     * @param classNames 参数
     * @return 返回值
     */
    @Override
    public boolean deleteByClassNames(List<String> classNames) {
        if (classNames == null || classNames.size() < 1) {
            throw new BusinessException("999999", "模型类名称列表不能为空,删除模型实例失败！");
        }
        try {
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("className", classNames);
            queryWrapper.eq("published", true);
            //删除实例
            this.statisticsInstanceService.realDelete(queryWrapper);
            return true;
        } catch (Exception ex) {
            throw new BusinessException("999999", "模型类名称列表删除模型失败！");
        }
    }

    /**
     * 按Id 废除模型
     * @param ids 参数
     * @return 返回结果
     */
    public boolean repealByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            throw new BusinessException("999999", "ids列表不能为空，废除模型失败！");
        }
        //删除缓存
        try {
            QueryWrapper<StatisticsInstance> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", ids);
            queryWrapper.eq("published", true);
            //删除实例
            this.statisticsInstanceService.remove(queryWrapper);
            return true;
        } catch (Exception ex) {
            throw new BusinessException("999999", "按ids删除模型失败！", ex);
        }

    }

    /**
     * 批量废除
     *
     * @param classNames 参数
     * @return 返回值
     */
    @Override
    public boolean repealByClassNames(List<String> classNames) {
        if (classNames == null || classNames.size() < 1) {
            throw new BusinessException("999999", "模型类名称列表不能为空,删除模型失败！");
        }
        try {
            QueryWrapper<StatisticsModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("className", classNames);
            queryWrapper.eq("published", true);
            //删除模型
            this.statisticsModelService.remove(queryWrapper);
            return true;
        }catch (Exception ex){
            throw new BusinessException("999999", "模型类名称列表删除模型实例失败！");
        }
    }

    /**
     * 获取分页查询
     * @param pageInfo 分页信息
     * @param queryWrapper 查询wrapper
     * @return 返回结果
     */
    private PageInfo getPageInfoResult(Page<StatisticsInstance> pageInfo, QueryWrapper<StatisticsInstance> queryWrapper,boolean isInfo) {
        Page<StatisticsInstance> queryPage = statisticsInstanceService.page(pageInfo, queryWrapper);
        List<StatisticsInstance> records = queryPage.getRecords();
        List<JSONObject> jsonObjectList;
        if(isInfo){
            jsonObjectList = this.getStatisticsInsInfoJsonObjectList(records);
        }else{
            jsonObjectList = this.getStatisticsInsJsonObjectList(records);
        }
        Page<JSONObject> queryPageDTO = new Page<>();
        BeanUtils.copyProperties(queryPage, queryPageDTO);
        queryPageDTO.setRecords(jsonObjectList);
        return PageInfo.of(queryPageDTO);
    }

    /**
     * 检查模型是否存在
     * @param type 类型
     * @param className 类名称
     * @return 返回是否存，true 存在，false 不存在
     */
    private boolean existModel(String type, String className) {
        QueryWrapper<StatisticsModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(type), "type", type);
        queryWrapper.eq(StringUtils.isNotBlank(className), "className", className);
        queryWrapper.eq("published", true);
        long count = this.statisticsModelService.count(queryWrapper);
        return count > 0;
    }

    /**
     * 将模型实例列表转成JSONObject 列表
     *
     * @param instances 模型实例
     * @return 返回结果
     */
    public List<JSONObject> getStatisticsInsInfoJsonObjectList(List<StatisticsInstance> instances) {
        List<JSONObject> jsonList = new ArrayList<>();
        instances.forEach(ins -> {
            JSONObject infoJsonObject = ins.getInfoJsonObject();
            jsonList.add(infoJsonObject);

        });
        return jsonList;
    }

    /**
     * 将模型实例列表转成JSONObject 列表
     *
     * @param instances 模型实例
     * @return 返回结果
     */
    public List<JSONObject> getStatisticsInsJsonObjectList(List<StatisticsInstance> instances) {
        List<StatisticsModel> models = this.statisticsModelService.list();
        List<JSONObject> jsonList = new ArrayList<>();
        instances.forEach(ins -> {
            StatisticsModel statisticsModel = models.stream().filter(m -> m.getClassName().equalsIgnoreCase(ins.getClassName())).findFirst().orElse(null);
            JSONObject insJsonObject = ins.getInsJsonObject(statisticsModel);
            jsonList.add(insJsonObject);
        });
        return jsonList;
    }

    /**
     * 查询条件字段转换
     *
     * @param condition            参数
     * @param className            参数
     */
    public String transformConditionForStatistics(String condition, String className) {
        if (StringUtils.isBlank(condition)) {
            return "";
        }
        if (StringUtils.isBlank(className)) {
            className = queryBuilder.getClassNameBy(condition);
        }
        if (StringUtils.isBlank(className)) {
            return condition;
        }
        if (StringUtils.isNotBlank(className) && StringUtils.isNotBlank(condition)) {
            StatisticsModel statisticsModel = modelCacheDslService.queryModel(ModelType.Statistics.getCode(), className);
            if (statisticsModel != null) {
                List<JSONObject> featureProperties = statisticsModel.fetchFeatureProperties();
                for (JSONObject item : featureProperties) {
                    String name = item.getString("name");
                    String code = item.getString("code");
                    // condition = condition.replaceAll(name, code);
                    condition = condition.replaceAll("(?<!['%a-z0-9_\\u4e00-\\u9fa5])"+name, code);
                }
            }
        }
        return condition;
    }

    /**
     * 查询条件字段转换
     *
     * @param condition 取className 条件
     * @param className 类名
     * @param orderBy   排序参数
     */
    public String transformOrderByForStatistics(String condition, String className, String orderBy) {
        if (StringUtils.isBlank(orderBy)) {
            return "";
        }
        if (StringUtils.isBlank(className)) {
            className = queryBuilder.getClassNameBy(condition);
        }

        if (StringUtils.isBlank(className)) {
            return orderBy;
        }
        orderBy = orderBy.replaceAll(" ", "");
        StatisticsModel statisticsModel = modelCacheDslService.queryModel("statistics", className);
        List<JSONObject> featureProperties = statisticsModel.fetchFeatureProperties();
        for (JSONObject item : featureProperties) {
            String name = item.getString("name");
            String code = item.getString("code");
            orderBy = orderBy.replaceAll(name, code);
        }
        return orderBy;
    }



}
